#ifndef __CEIL__HPP__
#define __CEIL__HPP__
// Ceil
struct Ceil {
  static std::string name() { return "CEIL"; }
  // constexpr only if proper definition using actual modulo and remainder
  // static int apply (int l, int h) { 
  //   return ceil(((double)(l))/((double)(h))); 
  // }

  constexpr static int apply (int l, int h) { 
    return (((l > 0 && h > 0) || (l < 0 && h < 0)) && (l % h) != 0) ? l/h+1 : l/h;
  }
};

template< class A>
constexpr Expression<BinaryExpression<Expression<A>, Expression<ConstantTerm>, Ceil> >
ceil(Expression<A> a, int const & b)
{
  typedef BinaryExpression <Expression<A>, Expression<ConstantTerm>, Ceil> ExprT;
  return Expression<ExprT>(ExprT(a,Expression<ConstantTerm>(b)));
}
template <int PLACE>
constexpr Expression<BinaryExpression<Expression<VariableTerm<PLACE> >, Expression<ConstantTerm>, Ceil> >
ceil(VariableTerm<PLACE> const & b, ConstantTerm const & a) {
  typedef BinaryExpression <Expression<VariableTerm<PLACE> >, Expression<ConstantTerm>, Ceil> ExprT;
  return Expression<ExprT>(ExprT(Expression<VariableTerm<PLACE> >(b), Expression<ConstantTerm>(a)));
}
constexpr Expression<BinaryExpression<Expression<ConstantTerm>, Expression<ConstantTerm>, Ceil> >
ceil(ConstantTerm const & b, ConstantTerm const & a) {
  typedef BinaryExpression <Expression<ConstantTerm>, Expression<ConstantTerm>, Ceil> ExprT;
  return Expression<ExprT>(ExprT(Expression<ConstantTerm>(b), Expression<ConstantTerm>(a)));
}

#endif //__CEIL__HPP__
